#!/usr/bin/env perl

use warnings;
use strict;

use File::Find::Rule;

use File::Which qw(which);
use Carp qw(croak);

my $s3cmd = 's3cmd';
my $site_path = "$ENV{HOME}/public_html";
my $site_name = 'TylerCipriani';
my $bucket = 'tylercipriani.com';

# Name of subpath in site
my $bucket_prefix = '';

sub updateMimeForFile($$) {
    my $file = shift;
    my $mime = shift;

    if ( not $bucket_prefix =~ /\/$/) {
        $bucket_prefix .= '/';
    }

    my @cmd = ($s3cmd, 'setacl');
    push(@cmd, '--acl-public', "--mime-type='${mime}'");

    my @headerCmd = ($s3cmd, 'modify');
    push(@headerCmd, "--add-header='Content-type:${mime}'");

    my $s3Path = 's3://' . $bucket . $bucket_prefix . $file;

    system(join(' ', @cmd) . ' ' . $s3Path . ' >/dev/null 2>&1');
    system(join(' ', @headerCmd) . ' ' . $s3Path . ' >/dev/null 2>&1');
}

sub checkCachedMtime($$$) {
    my $extension = shift;
    my $mime = shift;
    my $callback = shift;

    my $ucExtension = ucfirst $extension;

    my $allFilesFound = File::Find::Rule->file()->name('*.' . $extension);
    my $fileDB = "$ENV{HOME}/.ikiwiki${ucExtension}DB";
    my $common_path = $site_path . '/' . $site_name;
    my %dbFiles;

    if (open(my $fh, '<', $fileDB)) {
        while (my $line = <$fh>) {
            chomp $line;
            my @nameSum = split(/:/, $line);
            $dbFiles{$nameSum[0]} = $nameSum[1];
        }

        close($fh);
    }

    open(my $writeFh, '>', $fileDB)
        or die "Can't open $fileDB";

    foreach my $foundFile ($allFilesFound->in($common_path)) {
        my $mtime = (stat($foundFile))[9];
        if ( $foundFile =~ s/^$common_path\/// ) {
            print $writeFh "${foundFile}:${mtime}\n";
            if (defined $dbFiles{$foundFile} &&
                $dbFiles{$foundFile} != $mtime) {
                    $callback->($foundFile, $mime);
            }
        }
    }

    close($writeFh);
}

sub jsonfiles {
    checkCachedMtime('json', 'application/json', \&updateMimeForFile);
}

sub cssfiles {
    checkCachedMtime('css', 'text/css', \&updateMimeForFile);
}

sub update {
    chdir($site_path);
    if ( not -f "$site_name/index.html" ) {
        die("Could not find $site_name/index.html in $site_path");
    }

    if ( not $bucket_prefix ) {
        $bucket_prefix = '/';
    }

    if ( not $bucket_prefix =~ /\/$/) {
        $bucket_prefix .= '/';
    }

    my @cmd = ($s3cmd, 'sync');
    push(@cmd, "--add-header='Expires:max-age=604800'");
    push(@cmd, "--exclude '.git/*'");
    push(@cmd, "--exclude 'ikiwiki.cgi'");
    push(@cmd, "--exclude 'robots.txt'");
    push(@cmd, "--acl-public");
    push(@cmd, $site_name . '/');
    push(@cmd, 's3://' . $bucket . $bucket_prefix);
    push(@cmd, '>/dev/null');
    push(@cmd, '2>&1');

    system(join(' ', @cmd));

    cssfiles;
    jsonfiles;
}

sub main {
    $s3cmd = which($s3cmd);

    if ( not -x "$s3cmd" ) {
        croak("Couldn't find s3cmd");
    }

    update;
}

main;
